package binaryTree;

import java.util.*;

/**
 * @program: data_structures_algorithms
 * @description: 使用栈 遍历二叉树
 * @author: lld
 * @create: 2021-03-25 22:17
 **/
public class StackPre {
    public static void main(String[] args) {
        TreeNode1 treeNode1 = new TreeNode1(1);
        TreeNode1 treeNode11 = new TreeNode1(2);
        TreeNode1 treeNode12 = new TreeNode1(3);
        TreeNode1 treeNode13 = new TreeNode1(4);
        TreeNode1 treeNode14 = new TreeNode1(5);
        treeNode1.left = treeNode11;
        treeNode1.right = treeNode12;
        treeNode11.left = treeNode13;
        treeNode11.right = treeNode14;

        List<Integer> list = printPre(treeNode1);
//        根节点的遍历顺序在前面
        System.out.println("前序：" + list);
        List<Integer> list1 = printIn(treeNode1);
        System.out.println("中序：" + list1);
//        Deque<Integer> deque = printAft(treeNode1);
//        System.out.println("后序：" + deque);
        List<Integer> list2 = printAft(treeNode1);
        System.out.println("后序：" + list2);

    }

    public static List<Integer> printPre(TreeNode1 root) {
        Stack<TreeNode1> stack = new Stack<>();
        List<Integer> list = new ArrayList<>();
        while (root != null || !stack.isEmpty()) {
            if (root != null) {
//                前序入栈时就输出
                list.add(root.val);
                stack.push(root);
                root = root.left;
            } else {
                root = stack.pop();
                root = root.right;
            }
        }
        return list;
    }

    public static List<Integer> printIn(TreeNode1 root) {
        Stack<TreeNode1> stack = new Stack<>();
        List<Integer> list = new ArrayList<>();
        while (root != null || !stack.isEmpty()) {
            if (root != null) {
                stack.push(root);
                root = root.left;
            } else {
                root = stack.pop();
//                中序在出栈时输出
                list.add(root.val);
                root = root.right;
            }
        }
        return list;
    }

    public static List<Integer> printAft(TreeNode1 root) {
//        Deque<Integer> deque = new LinkedList<>();
//        List<Integer> list = new LinkedList<>();
        LinkedList<Integer> list = new LinkedList<>();

        Stack<TreeNode1> stack = new Stack<>();
        while (root != null || !stack.isEmpty()) {
            if (root != null) {
                stack.push(root);
//                deque.addFirst(root.val);
//                使用LinkedList头插
                list.addFirst(root.val);
//                注意这里与前序相反，先访问右节点
                root = root.right;
            } else {
                root = stack.pop();
                root = root.left;
            }
        }
        return list;
    }
}

class TreeNode1 {
    int val;
    TreeNode1 left;
    TreeNode1 right;

    public TreeNode1(int val) {
        this.val = val;
    }
}
